const particle =/*wgsl*/`
const PI =3.1415926535897932384626433832795;
const DEG2RAD =PI / 180;
struct Particle {
    position : vec3<f32>,
    padding: f32,        // 4 bytes (用于对齐) 
    color    : vec3<f32>,
    padding2: f32,       // 4 bytes (用于对齐)  
    velocity : vec3<f32>,
    padding3: f32,       // 4 bytes (用于对齐)  
    size : f32,
    opacity:f32,
    age : f32,
    angle: f32,
  }
  struct Particles {
    particles : array<Particle>,
  }
  struct Colors {
    color : array<vec3<f32>>,
  }
  struct Sizes {
    size : array<f32>,
  }
  struct Opacitys {
    opacity : array<f32>,
  }
  struct Times {
    time : array<f32>,
  }
  struct EmitterParams {
    position : vec3<f32>,
    positionShape : f32,
    positionRange : vec3<f32>,
    positionRadius:f32,

    velocity:vec3<f32>,
    velocityShape:f32,
    velocityRange:vec3<f32>,
    velocityRadius:f32,


    acceleration:vec3<f32>,
    angle:f32,
    angleRange:f32,
    angleVelocity:f32,
    positionconeHeight:f32,
    duration : f32,
    velocityconeHeight:f32,
  }
  struct FrameParams {
    deltaTime : f32,
    frameID : f32,
  }
  @group(0) @binding(0)  var<uniform> params : EmitterParams;
  @group(0) @binding(1)  var<uniform> frameParams : FrameParams;
  @group(0) @binding(2)  var<storage, read> sizes : Sizes;
  @group(0) @binding(3)  var<storage, read> sizeTimes:Times;
  @group(0) @binding(4)  var<storage, read> colors : Colors;
  @group(0) @binding(5)  var<storage, read> colorTimes :Times;
  @group(0) @binding(6)  var<storage, read> opacitys : Opacitys;
  @group(0) @binding(7)  var<storage, read> opacityTimes : Times;
  @group(0) @binding(8)  var<storage, read_write> data : Particles;
  @group(0) @binding(9)  var<storage, read_write> debuggers : array<u32>;
  // var<private> rand_seed : vec2f;
  // fn init_rand(invocation_id : u32, seed : vec4f) {
  //   rand_seed = seed.xz;
  //   rand_seed = fract(rand_seed * cos(35.456+f32(invocation_id) * seed.yw));
  //   rand_seed = fract(rand_seed * cos(41.235+f32(invocation_id) * seed.xw));
  // }
  // fn rand() -> f32 {
  //   rand_seed.x = fract(cos(dot(rand_seed, vec2f(23.14077926, 232.61690225))) * 136.8168);
  //   rand_seed.y = fract(cos(dot(rand_seed, vec2f(54.47856553, 345.84153136))) * 534.7645);
  //   return rand_seed.y;
  // }
var<private> rand_seed : f32=0;
var<private> threadId: f32=0;
var<private> frameTime: f32=0;
fn hash() -> f32 {  
    // 这个函数例子可以根据需求自定义  
    var hashed = f32(threadId) + frameTime+rand_seed;  
    hashed = fract(sin(hashed) * 43758.5453);  
    rand_seed+=1.0;
    return hashed;  
}    
fn randomVector3(min: vec3<f32>, max: vec3<f32>) -> vec3<f32> {
  var rand3: vec3<f32> = vec3<f32>(hash(), hash(), hash()) - vec3<f32>(0.5, 0.5, 0.5);
  var scaledMax: vec3<f32> = max * rand3;
  return min + scaledMax;
}
fn randomValue(min: f32, max: f32) -> f32 {
  return min + max * (hash() - 0.5);
}

// fn interpolate(t: f32,times:array<f32,2>,values:array<f32,2>) -> f32 {
//   var index = 0;
//  var leng= arrayLength(times );
//   // 查找 t 所在的时间段
//   while (index < leng - 1 && t > values[index + 1].time) {
//       index += 1;
//   }
  
//   var t0 = values[index].time;
//   var t1 = values[index + 1].time;
//   var v0 = values[index].value;
//   var v1 = values[index + 1].value;
  
//   // 线性插值
//   var dt = t1 - t0;
//   return v0 + ((t - t0) / dt) * (v1 - v0);
// }
// // 插值函数  
// fn interpolateVec3(t: f32,times: array<f32>,values:array<vec3f>) -> vec3<f32> {  
//   // 找到 t 对应的关键帧  
//   var index: u32 = 0;  
//   // 遍历 times 数组找到 t 的插入位置  
//   for (var i: u32 = 0; i < arrayLength(times) - 1; i = i + 1) {  
//       if (t >= times[i] && t <= times[i + 1]) {  
//           index = i;  
//           break;  
//       }  
//   }  

//   // 计算插值的比例  
//   var t0: f32 = times[index];  
//   var t1: f32 = times[index + 1];  
//   var value0: vec3<f32> = values[index];  
//   var value1: vec3<f32> = values[index + 1];  

//   // 计算插值比例  
//   var alpha: f32 = (t - t0) / (t1 - t0);  
  
//   // 返回插值结果  
//   return mix(value0, value1, alpha);  
// }
fn randomInRange(min: vec3<f32>, max: vec3<f32>, seed: u32) -> vec3<f32> {  
  // 使用简单的伪随机数生成算法  
  // 只需确保这一部分可以产生重复的结果  
  let randomValue = f32(seed) * 0.5 + 0.1; // 确保是正数  

  let randomX = min.x + fract(sin(randomValue) * 43758.5453) * (max.x - min.x);  
  let randomY = min.y + fract(sin(randomValue * 1.5) * 43758.5453) * (max.y - min.y);  
  let randomZ = min.z + fract(sin(randomValue * 3.0) * 43758.5453) * (max.z - min.z);  
  
  return vec3<f32>(randomX, randomY, randomZ);  
}  
var<private> p : Particle;
@compute @workgroup_size(64)
fn main(   
@builtin(workgroup_id) workgroup_id : vec3<u32>,
@builtin(local_invocation_id) local_invocation_id : vec3<u32>,
@builtin(global_invocation_id) global_invocation_id : vec3<u32>,
@builtin(local_invocation_index) local_invocation_index: u32,
@builtin(num_workgroups) num_workgroups: vec3<u32>)
{
  let idx = global_invocation_id.x;
  threadId=f32(idx);
  frameTime=frameParams.frameID;
  if (idx >= arrayLength(&data.particles)) {
    return;
  }
  // init_rand(idx, frameParams.seed);
  var particle = data.particles[idx];
  // 更新粒子的位置  
  particle.position += particle.velocity * frameParams.deltaTime; // deltaTime 是帧时间  
  // 更新生命周期  
  particle.age -= frameParams.deltaTime;  
   // 如果粒子超出生命周期，重置它  
   if (particle.age<= 0.0) {  
    if(params.positionShape ==1.0){//box
      particle.position = randomVector3(params.position,params.positionRange);
    }
    particle.age = params.duration; // 重新设置生命周期  
}  
// 存储
  data.particles[idx] = particle;
  debuggers[idx]=idx;
}
`
export { particle }